package code17_reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;

public class Homework01 {

	/**
	 * 定义一个 静态的工具方法, 参数是 Class 类型,
	 * 根据参数创建一个 该类型的对象, 并返回; 如果无法创建对象, 则返回 null.
	 * 用户在使用该方法接收返回值时, 不需要进行类型强制转换就可以 使用对应的 类型 接收返回的 对象.
	 * 例如: 
	 *   <pre>
	 *   方法名为 getObj(Class c)
	 *   使用: Stu stu = getObj(Stu.class); 不需要强制类型转换
	 *   </pre>
	 */
	public static <T> T getObj(Class<T> c){
		try {
			T instance = c.newInstance();
			return instance;
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 输出类的简单结构
	 * 例如: 
	 * <pre>
	 * Stu.class -->
	 * package code17_reflect;
	 * public class Stu extends Person implements Serializable, Cloneable {
	 *     public String name;
	 *     private int age;
	 * }
	 * </pre>
	 * @param c
	 */
	public static void printClass(Class<?> c) {
		String s1 = ";";
		String s2 = " ";
		Package pkg = c.getPackage();
		System.out.println("package" + s2 + pkg.getName() + s1);
		
		String classModifiers = Modifier.toString(c.getModifiers());
		System.out.print(classModifiers);
		System.out.print(s2);
		
		System.out.print("class");
		System.out.print(s2);
		
		String classSimpleName = c.getSimpleName();
		System.out.print(classSimpleName);
		System.out.print(s2);
		
		Class<?> superclass = c.getSuperclass();
		if (null != superclass && Object.class != superclass) {
			String superClassSimpleName = superclass.getSimpleName();
			System.out.print("extends");
			System.out.print(s2);
			System.out.print(superClassSimpleName);
			System.out.print(s2);
		}
		
		Class<?>[] interfaces = c.getInterfaces();
		if (interfaces.length > 0) {
			System.out.print("implements");
			System.out.print(s2);
			for (int i = 0; i < interfaces.length; i++) {
				Class<?> ci = interfaces[i];
				String ciSimpleName = ci.getSimpleName();
				System.out.print(ciSimpleName);
				if (i < interfaces.length - 1) {
					System.out.print(",");
				}
				
				System.out.print(s2);
			}
		}
		System.out.println("{");
		
		
		Field[] fields = c.getDeclaredFields();
		
		for (Field f : fields) {
			int modifiers = f.getModifiers();
			System.out.print("\t");
			
			System.out.print(Modifier.toString(modifiers));
			System.out.print(" ");
			
			Class<?> fieldType = f.getType();
			System.out.print(fieldType.getSimpleName());
			System.out.print(" ");
			
			String name = f.getName();
			System.out.print(name);
			System.out.println(s1);
		}
		
		Method[] methods = c.getDeclaredMethods();

		for (Method m : methods) {
			System.out.print("\t");
			String modifiers = Modifier.toString(m.getModifiers());
			Class<?> returnType = m.getReturnType();
			String name = m.getName();
			//Parameter[] parameters = m.getParameters();
			Class<?>[] parameterTypes = m.getParameterTypes();
			Class<?>[] exceptionTypes = m.getExceptionTypes();
			System.out.print(
					modifiers + " "
					+ returnType.getSimpleName() + " "
					+ name + "("
					//+ Arrays.toString(parameterTypes) + ") "
					//+ "throws " + Arrays.toString(exceptionTypes) + " { }"
					);
			
			// 参数
			if (parameterTypes.length > 0) {
				for (int j = 0; j < parameterTypes.length; j++) {
					Class<?> pt = parameterTypes[j];
					System.out.print(pt.getSimpleName());
					System.out.print(" arg"+j);
					
					if (j < parameterTypes.length - 1) {
						System.out.print(",");
						System.out.print(s2);
					}
				}
			}
			System.out.print(")");
			
			// 异常
			if (exceptionTypes.length > 0) {
				System.out.print(" throws ");
				for (int i = 0; i < exceptionTypes.length; i++) {
					Class<?> et = exceptionTypes[i];
					System.out.print(et.getSimpleName());
					if (i < exceptionTypes.length - 1) {
						System.out.print(",");
						System.out.print(s2);
					}
				}
			}
			
			System.out.println(" {} ");
		}
	
		System.out.println("}");
	}
	public static void main(String[] args) {
		printClass(Stu.class);
		
		printClass(String.class);
		
		printClass(Object.class);
	}
	
}
